<script setup lang="ts">
import { onMounted, ref } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// import matrix from "./data/3DData_id_1784_20250416_174508.json";
import matrix from "./data/3DData_id_1786_20250416_175353.json";
// import matrix from "./data/3DData_id_1833_20250418_165808.json";

/* dom */
const container = ref<HTMLDivElement | null>(null);
/* data */
const clock = new THREE.Clock();
const mouse = ref<THREE.Vector2>(new THREE.Vector2(0.0, 0.0));
const resolution = ref<THREE.Vector2>(new THREE.Vector2(0.0, 0.0));

onMounted(() => {
    init();

    window.addEventListener("mousemove", onMouse);
});

const init = () => {
    const { clientWidth, clientHeight } = container.value as HTMLDivElement;
    resolution.value.set(clientWidth, clientHeight);
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
        75,
        clientWidth / clientHeight,
        1,
        1000
    );
    camera.position.set(0, 0, 20);
    camera.lookAt(0, 0, 0);
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(clientWidth, clientHeight);
    container.value?.appendChild(renderer.domElement);

    // 添加环境光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    // 添加点光源
    // const light = new THREE.PointLight(0xffffff, 1);
    // light.position.set(10, 10, 10);
    // scene.add(light);

    const helper = new THREE.AxesHelper(10);
    scene.add(helper);

    const control = new OrbitControls(camera, renderer.domElement);

    initBox(scene);

    computed();

    function render() {
        control.update();
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
    render();
};

const initBox = (
    scene: THREE.Scene
): THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial> => {
    const xc = matrix.colNum / 2;
    const yc = matrix.rowNum / 2;
    const zc = matrix.zzNum / 2;

    const max = 500;

    const matrixData: number[][][] = matrix.concentrations3D; // 数据
    const group = new THREE.Group(); // 组
    const geo = new THREE.BoxGeometry(0.3, 0.3, 0.3);
    for (let y = 0; y < matrixData.length; y++) {
        const yItem = matrixData[y];
        for (let x = 0; x < yItem.length; x++) {
            const xItem = matrixData[y][x];
            for (let z = 0; z < xItem.length; z++) {
                const zItem = matrixData[y][x][z];
                const material = new THREE.MeshBasicMaterial({
                    color: new THREE.Color((zItem / max) * 100, 0, 0),
                    // transparent: true,
                    // opacity: 0.7,
                }); // 材质
                const mesh = new THREE.Mesh(geo, material);
                mesh.position.set(x - xc, y - yc, z - zc);
                group.add(mesh);
            }
        }
    }

    scene.add(group);

    return new THREE.Mesh();
};

// 3. 创建颜色映射函数
const getColorByValue = (value: number) => {
    const colors = [
        new THREE.Color(0x0000ff), // 低浓度 - 蓝色
        new THREE.Color(0x00ff00), // 中浓度 - 绿色
        new THREE.Color(0xff0000), // 高浓度 - 红色
    ];
    return colors[Math.floor(value * (colors.length - 1))];
};

const onMouse = (event: MouseEvent) => {
    const { x, y } = event;
    mouse.value.set(x, resolution.value.y - y);
};

const computed = () => {};
</script>

<template>
    <div ref="container" class="container"></div>
</template>

<style lang="less" scoped>
.container {
    width: 100%;
    height: 100%;
}
</style>
